home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / pcl / src-16f.lha / compiler / assembler.lisp < prev    next >
Encoding:
Text File  |  1992-02-24  |  45.5 KB  |  1,399 lines

  1. ;;; -*- Package: ASSEMBLER; Log: C.Log -*-
  2. ;;;
  3. ;;; **********************************************************************
  4. ;;; This code was written as part of the CMU Common Lisp project at
  5. ;;; Carnegie Mellon University, and has been placed in the public domain.
  6. ;;; If you want to use this code or any part of CMU Common Lisp, please contact
  7. ;;; Scott Fahlman or slisp-group@cs.cmu.edu.
  8. ;;;
  9. (ext:file-comment
  10.   "$Header: assembler.lisp,v 1.25 92/02/24 06:18:26 wlott Exp $")
  11. ;;;
  12. ;;; **********************************************************************
  13. ;;;
  14. ;;; Assembler for the compiler.
  15. ;;;
  16. ;;; Written by William Lott.  Instruction definition stuff rewritten by Rob
  17. ;;; MacLachlan to support instruction scheduling.
  18. ;;;
  19. (in-package "ASSEMBLER" :nicknames '("ASSEM"))
  20. (use-package "C")
  21. (use-package "EXTENSIONS")
  22. (use-package "KERNEL")
  23.  
  24. ;;; Import freelisting allocators...
  25. (import '(c::really-make-instruction c::make-instruction
  26.                      c::unmake-instruction))
  27. (export '(
  28.       define-format define-argument-type define-fixup-type
  29.       define-instruction define-pseudo-instruction
  30.       define-resources define-register-file
  31.  
  32.       make-fixup fixup fixup-p fixup-name fixup-flavor fixup-offset
  33.  
  34.       gen-label label label-id label-position emit-label
  35.       make-segment insert-segment assemble inst align
  36.  
  37.       expand-pseudo-instructions
  38.       finalize-segment *current-position* emit-code-vector
  39.       dump-segment nuke-segment count-instructions
  40.       relative-branch unconditional-branch delayed-branch nop delayed-load
  41.       assembly-call))
  42.  
  43.  
  44. ;;; Meta-compile-time data structures.
  45.  
  46. (eval-when (compile load eval)
  47.  
  48. ;;; Meta-compile-time representation of an instruction's properties, used to
  49. ;;; compute the miscellanous values of the INSTRUCTION-INFO, below.
  50. ;;;
  51. (defstruct (meta-instruction
  52.         (:make-load-form-fun :just-dump-it-normally))
  53.   ;;
  54.   ;; Lists of resource names used and clobbered.
  55.   (use nil :type list :read-only t)
  56.   (clobber nil :type list :read-only t)
  57.   ;;
  58.   ;; True if this instruction can never be moved, nor have anything moved over
  59.   ;; it.  Used for branches and other odd things.
  60.   (pinned nil :type boolean :read-only t)
  61.   ;;
  62.   ;; The cost of this instruction, in cycles (or whatever.)
  63.   (cost 1 :type index :read-only t)
  64.   ;;
  65.   ;; List of boolean attribute names.
  66.   (attributes nil :type list :read-only t)
  67.   ;;
  68.   ;; Some other info used by the optimizer, organized as a plist.  The values
  69.   ;; of the properties are forms that are evaluated at load-time to produce the
  70.   ;; real plist values.
  71.   (properties nil :type list :read-only t))
  72.  
  73.  
  74. ;;; The info about a single instruction format.
  75. ;;; 
  76. (defstruct (cformat (:conc-name format-) (:constructor make-format))
  77.   ;;
  78.   ;; The name of this format.  User supplied.
  79.   (name nil :type symbol :read-only t)
  80.   ;;
  81.   ;; The number of bits an instruction of this format takes.
  82.   (length 0 :type index :read-only t)
  83.   ;;
  84.   ;; A list of all the fields of this format.
  85.   (fields nil :type list :read-only t)
  86.   ;;
  87.   ;; The META-INSTRUCTION holding default values for instruction attributes.
  88.   (meta-instruction (required-argument) :type meta-instruction :read-only t)
  89.   ;;
  90.   ;; The name of the generated function that emits an instruction of this
  91.   ;; format.  This function expects to be passed the output buffer vector and
  92.   ;; the location at which to begin emitting, followed by an integer argument
  93.   ;; for each field defined in the format.
  94.   (emitter nil :type symbol :read-only t))
  95.  
  96.  
  97. ;;; Info about a single field of an instruction format.
  98. ;;;
  99. (defstruct field
  100.   ;;
  101.   ;; Its name -- user supplied.
  102.   (name nil :type symbol :read-only t)
  103.   ;;
  104.   ;; The default value for this field (if any).
  105.   (default nil :read-only t)
  106.   ;;
  107.   ;; T iff this field can be defaulted.
  108.   (default-p nil :type (member t nil) :read-only t)
  109.   ;;
  110.   (default-type nil :type (or null symbol cons))
  111.   ;;
  112.   ;; Flags indicating whether this field is read or written.  If either is
  113.   ;; true, then the actual argument must be a TN.  This is a default that can
  114.   ;; be overridden in the instruction definition.
  115.   (read-p nil :type boolean :read-only t)
  116.   (write-p nil :type boolean :read-only t))
  117.  
  118.  
  119. ;;; Info about a field in a particular instruction flavor.  This is the
  120. ;;; instantiation of a format field.
  121. ;;;
  122. (defstruct field-parse
  123.   ;;
  124.   ;; This is the field name copied from the format.
  125.   (name nil :type symbol :read-only t)
  126.   ;;
  127.   ;; The way this field is supplied:
  128.   (kind (required-argument) :type (member :constant :argument :same-as)
  129.     :read-only t)
  130.   ;;
  131.   ;; The constant value, argument type or same-as argument name.
  132.   (what (required-argument) :read-only t)
  133.   ;;
  134.   ;; A function name that is applied to the field value to get the true value,
  135.   ;; or null if none.
  136.   (function nil :read-only t)
  137.   ;;
  138.   ;; If true, the cons (Actual-Type . Function) for a special argument field.
  139.   ;; This is just the result of GETHASH on WHAT in the backend special argument
  140.   ;; types.
  141.   (special-type nil :type (or cons null) :read-only t)
  142.   ;;
  143.   ;; If :ARGUMENT, the list of all the slot accessor names for slots that hold
  144.   ;; this value in the INSTRUCTION structure.  If a slot is both read and
  145.   ;; written, then there will be two elements in this list.
  146.   (accessors nil :type list)
  147.   ;;
  148.   ;; If :ARGUMENT, the name of the argument to the selector function that will
  149.   ;; hold the value.
  150.   (argument nil :type symbol)
  151.   ;;
  152.   ;; Flags indicating whether this field is read or written.  If either is
  153.   ;; true, then the actual argument must be a TN.  These are defaulted from the
  154.   ;; format field, but may be overridden.
  155.   (read-p nil :type boolean :read-only t)
  156.   (write-p nil :type boolean :read-only t))
  157.  
  158.  
  159. ;;; The result of parsing a particular instruction flavor.
  160. ;;;
  161. (defstruct instruction-flavor
  162.   ;;
  163.   ;; The name of this flavor's instruction.
  164.   (name (required-argument) :type symbol :read-only t)
  165.   ;;
  166.   ;; The format of this instruction flavor.
  167.   (format (required-argument) :type cformat :read-only t)
  168.   ;;
  169.   ;; This flavor's ordinal number.
  170.   (number (required-argument) :type index :read-only t)
  171.   ;;
  172.   ;; The list of FIELD-INFO structures.
  173.   (fields (required-argument) :type list :read-only t)
  174.   ;;
  175.   ;; The Lisp types of the arguments to this flavor (used to select this over
  176.   ;; other flavors.)
  177.   (arg-types (required-argument) :type list :read-only t)
  178.   ;;
  179.   ;; The number of arguments to this flavor.
  180.   (nargs (required-argument) :type index :read-only t)
  181.   ;;
  182.   ;; The META-INSTRUCTION representing all the defaulted attributes of this
  183.   ;; instruction.
  184.   (meta-instruction (required-argument) :type meta-instruction :read-only t)
  185.   ;;
  186.   ;; The lexical variable we close over to get our hands on the INSTRUCTION-INFO.
  187.   (info-var (gensym) :type symbol :read-only t))
  188.  
  189. ); eval-when (compile load eval)
  190.  
  191.  
  192. ;;; Assemble time data structures.
  193.  
  194. ;;; Specials used during code generation.  See the defvars below.
  195.  
  196. (proclaim '(special *current-segment* *current-vop*
  197.             *fixups* *current-position*))
  198.  
  199. ;;;
  200. ;;; The assembler runs in several passes.  This first pass generates a doubly
  201. ;;; linked list of different kind of node structures, and the later passes
  202. ;;; grovel this list.
  203.  
  204. ;;; Generic node, everything the assembler needs to emit in the instruction
  205. ;;; stream includes this.
  206. ;;; 
  207. (defstruct (node
  208.         (:print-function %print-node))
  209.   ;; The ir2 vop this node was emited on behalf of or other useful
  210.   ;; identification info.  Used during trace file dumps.
  211.   (vop *current-vop*)
  212.   ;; The next and previous node (if any).
  213.   (next nil :type (or null node))
  214.   (prev nil :type (or null node)))
  215.  
  216.  
  217. (def-boolean-attribute instruction
  218.   ;;
  219.   ;; True if this is a branch to an assembler label, which must be a constant
  220.   ;; argument to the instruction.
  221.   relative-branch
  222.   ;;
  223.   ;; True if this branch is always taken.
  224.   unconditional-branch
  225.   ;;
  226.   ;; True if this is a branch instruction with a delay slot that we want to
  227.   ;; fill.
  228.   delayed-branch
  229.   ;;
  230.   ;; True if this is a NOP instruction (which is initially placed in delay
  231.   ;; slots).
  232.   nop
  233.   ;;
  234.   ;; True if this is a load with a delay slot that we want to fill.  The result
  235.   ;; of this instruction must not be read in the delay slot.
  236.   delayed-load
  237.   ;;
  238.   ;; True if this instruction is used to call assembly routines.  Used by
  239.   ;; lifetime checking to detect these calls (which are not flagged by
  240.   ;; vop-info-save-p.)
  241.   assembly-call)
  242.  
  243. ;;; This structure holds run-time info about a particular instruction that is
  244. ;;; in common with all instances of that instruction.
  245. ;;;
  246. (defstruct instruction-info
  247.   ;;
  248.   ;; The name of this instruction.
  249.   (name (required-argument) :type symbol :read-only t)
  250.   ;;
  251.   ;; A small integer indicating which flavor of this instruction that we are
  252.   ;; describing here.
  253.   (flavor (required-argument) :type index)
  254.   ;;
  255.   ;; The kind of instruction.
  256.   (kind (required-argument) :type (member :pseudo :normal) :read-only t)
  257.   ;;
  258.   ;; The maximum length of this instruction.
  259.   (length (required-argument) :type index :read-only t)
  260.   ;;
  261.   ;; The sets of resources that this instruction uses and clobbers.
  262.   (use 0 :type index :read-only t)
  263.   (clobber 0 :type index :read-only t)
  264.   ;;
  265.   ;; True if this instruction can never be moved, nor have anything moved over
  266.   ;; it.  Used for branches and other odd things.
  267.   (pinned nil :read-only t)
  268.   ;;
  269.   ;; Some boolean attributes of this instruction used by the optimizer.
  270.   (attributes 0 :type attributes :read-only t)
  271.   ;;
  272.   ;; The cost of this instruction, in cycles (or whatever.)
  273.   (cost 0 :type index :read-only t)
  274.   ;;
  275.   ;; Some other info used by the optimizer, organized as a plist.
  276.   (properties nil :type list :read-only t)
  277.   ;;
  278.   ;; Function that converts this instruction into real stuff.
  279.   ;;
  280.   ;; If a :PSEUDO instruction, then this function is called with the
  281.   ;; INSTRUCTION structure during the pseudo-instruction expansion pass.  The
  282.   ;; result of the expansion should be inserted into the current segment.  The
  283.   ;; pseudo-instruction argument list is in the first constant slot.
  284.   ;;
  285.   ;; If a :NORMAL instruction, then this function is called at the end of
  286.   ;; assembly to actually emit the bits.  It is called with the output buffer
  287.   ;; and starting index, and the INSTRUCTION structure.
  288.   (emitter (required-argument) :type function :read-only t))
  289.  
  290.  
  291. ;;; DEFINE-INSTRUCTION-STRUCTURE  --  Internal
  292. ;;;
  293. ;;;    This macro is used to define the instruction structure with some set of
  294. ;;; possible arguments and results.  This must be set up for worst-case for all
  295. ;;; the hardware that we want to simultaneously support.  If you change the
  296. ;;; below call to this macro, you have to recompile the assembler.
  297. ;;;
  298. (defmacro define-instruction-structure (&key arguments results constants)
  299.   (declare (type (integer 1 10) arguments results constants))
  300.   (collect ((arg-names)
  301.         (res-names)
  302.         (const-names)
  303.         (slots))
  304.     (macrolet ((frob (count res what type)
  305.          `(dotimes (i ,count)
  306.             (let ((name (format nil "~:@(~R~)" i)))
  307.               (,res (symbolicate "INSTRUCTION-" ,what name))
  308.               (slots `(,(symbolicate ,what name) nil :type ,',type))))))
  309.       (frob arguments arg-names "ARGUMENT-" (or tn null))
  310.       (frob results res-names "RESULT-" (or tn null))
  311.       (frob constants const-names "CONSTANT-" t))
  312.     (let ((all-accessors (append (arg-names) (res-names) (const-names))))
  313.       `(progn
  314.      (eval-when (compile load eval)
  315.        (defconstant instruction-argument-slots ',(arg-names))
  316.        (defconstant instruction-result-slots ',(res-names))
  317.        (defconstant instruction-constant-slots ',(const-names))
  318.        (defconstant instruction-slot-order ',all-accessors))
  319.      (export ',all-accessors)
  320.      
  321.      (declaim (inline really-make-instruction))
  322.      (defstruct (instruction
  323.              (:include node)
  324.              (:print-function %print-instruction)
  325.              (:constructor really-make-instruction
  326.                    (prev info ,@(mapcar #'car (slots)))))
  327.        ;;
  328.        ;; The INSTRUCTION-INFO for this instruction.
  329.        (info nil :type instruction-info)
  330.        ;;
  331.        ;; The arg, result and constant slots.  Args and results are the TNs
  332.        ;; read & written by this instruction, or NIL if the slot is not used.
  333.        ;; Constants can be anything.
  334.        ,@(slots))))))
  335. ;;;
  336. (define-instruction-structure :arguments 4  :results 1  :constants 3)
  337.  
  338.  
  339. ;;; DO-ARGUMENTS, DO-RESULTS, DO-CONSTANTS  --  Public
  340. ;;;
  341. (macrolet ((frob (name slots)
  342.          `(defmacro ,name ((var instruction &optional res) &body body)
  343.         (once-only ((n-inst instruction))
  344.           `(block nil
  345.              ,@(mapcar #'(lambda (x)
  346.                    `(let ((,var (,x ,n-inst)))
  347.                       (when ,var 
  348.                     ,@body)))
  349.                    ,slots)
  350.              ,res)))))
  351.   (frob do-arguments instruction-argument-slots)
  352.   (frob do-results instruction-result-slots)
  353.   (frob do-constants instruction-constant-slots))
  354.  
  355.  
  356. ;;; INSTRUCTION-xxx  --  Interface
  357. ;;;
  358. (declaim (inline instruction-name instruction-length))
  359. (defun instruction-name (x)
  360.   (instruction-info-name (instruction-info x)))
  361. (defun instruction-length (x)
  362.   (instruction-info-length (instruction-info x)))
  363.  
  364. ;;; Labels.
  365. ;;; 
  366. (defstruct (label
  367.         (:include node (vop nil))
  368.         (:constructor gen-label)
  369.         (:print-function %print-label))
  370.   ;; The current guess at where this instruction is located in the instruction
  371.   ;; stream.
  372.   (%position nil :type (or null fixnum)))
  373.  
  374.   
  375. ;;; Segments.
  376. ;;; 
  377. (defstruct (segment
  378.         (:include label)
  379.         (:print-function %print-label)
  380.         (:constructor %make-segment))
  381.   ;; The last node inserted in this segment.  Additional nodes are inserted
  382.   ;; after it.
  383.   (last nil :type (or null node)))
  384.  
  385. ;;; Alignment tweek.
  386. ;;; 
  387. (defstruct (alignment
  388.         (:include node)
  389.         (:print-function %print-alignment))
  390.   ;; The number of low order bits that must be zero.
  391.   (bits 0 :type (integer 0 32)))
  392.  
  393. ;;; A fixup record.
  394. ;;; 
  395. (defstruct (fixup
  396.         (:print-function %print-fixup)
  397.         (:constructor make-fixup (name flavor &optional offset)))
  398.   ;; The name and flavor of the fixup.  The assembler makes no assumptions
  399.   ;; about the contents of these fields; their semantics are imposed by the
  400.   ;; dumper.
  401.   name
  402.   flavor
  403.   ;; An optional offset from whatever external label this fixup refers to.
  404.   offset)
  405.  
  406.  
  407. (declaim (freeze-type node))
  408.  
  409.  
  410. ;;;; Print functions for structures
  411.  
  412. (defun %print-node (node stream depth)
  413.   (declare (ignore node depth))
  414.   (write-string "#<node???>" stream))
  415.  
  416. (defun %print-instruction (inst stream depth)
  417.   (declare (ignore depth))
  418.   (format stream "#<inst ~A>" (instruction-name inst)))
  419.  
  420. (defun %print-label (label stream depth)
  421.   (declare (ignore depth))
  422.   (if *print-escape*
  423.       (format stream "#<~A ~D>" (type-of label) (label-id label))
  424.       (format stream "L~D" (label-id label))))
  425.  
  426. (defun %print-alignment (align stream depth)
  427.   (declare (ignore depth))
  428.   (format stream "#<alignment to ~D bits>" (alignment-bits align)))
  429.  
  430. (defun %print-fixup (fixup stream depth)
  431.   (declare (ignore depth))
  432.   (format stream "#<~S fixup ~S~@[ offset=~S~]>"
  433.       (fixup-flavor fixup)
  434.       (fixup-name fixup)
  435.       (fixup-offset fixup)))
  436.  
  437.  
  438. ;;;; Hash tables and lookup functions.
  439.  
  440. (eval-when (compile load eval)
  441.  
  442. ;;; All the currently defined instruction formats.
  443. ;;;
  444. (defun format-or-lose (format)
  445.   (or (gethash format (backend-instruction-formats *target-backend*))
  446.       (error "Unknown instruction format: ~S" format)))
  447.  
  448. ;;; All the currently known flavors of instructions.  The print name of the
  449. ;;; instruction name is used as the key (to keep from having to export all the
  450. ;;; instruction names from some package).  The associated datum is an a-list
  451. ;;; mapping the number of arguments to the parser information.
  452. ;;; 
  453. (defun parser-or-lose (inst num-args)
  454.   (let ((entries (or (gethash (symbol-name inst)
  455.                   (backend-instruction-flavors *target-backend*))
  456.              (error "Unknown instruction: ~S" inst))))
  457.     (if (atom entries)
  458.     entries
  459.     (cdr (or (assoc num-args entries :test #'eql)
  460.          (error "Invalid number of arguments for ~S instruction: ~S"
  461.             inst num-args))))))
  462.  
  463.  
  464. ;;; RESOURCE-OR-LOSE  --  Internal
  465. ;;;
  466. ;;;    Return the resource number of the Named resource or die trying.
  467. ;;;
  468. (defun resource-or-lose (name)
  469.   (or (position name (backend-assembler-resources *target-backend*))
  470.       (error "~S is not a known resource." name)))
  471.  
  472.  
  473. ;;; PARSE-RESOURCES  --  Internal
  474. ;;;
  475. ;;;    Return a bit-mask with the named bits set.
  476. ;;;
  477. (defun parse-resources (names)
  478.   (let ((res 0))
  479.     (dolist (name names)
  480.       (setf (ldb (byte 1 (resource-or-lose name)) res) 1))
  481.     res))
  482.  
  483.  
  484. ;;;; Utilities:
  485.  
  486. (defun maybe-ash (form amt)
  487.   (if (zerop amt)
  488.       form
  489.       `(ash ,form ,amt)))
  490.  
  491. (defun maybe-funcall (function arg)
  492.   (if function
  493.       `(,function ,arg)
  494.       arg))
  495.  
  496.  
  497. ;;; NTH-ARGUMENT  --  Internal
  498. ;;; 
  499. ;;;    Return the name of the N'th argument to a selector function.
  500. ;;;
  501. (defun nth-argument (arg-num)
  502.   (intern (format nil "ARG-~D" arg-num) (symbol-package 'foo)))
  503.  
  504.  
  505. ;;;; Instruction parsing:
  506.  
  507. ;;; PARSE-INSTRUCTION-FIELDS  --  Internal
  508. ;;;
  509. ;;;    Return a list of Field-Parse structures corresponding to a particular
  510. ;;; instruction flavor.  Fields is a list of the field specs, and Format is the
  511. ;;; instruction format.
  512. ;;;
  513. (defun parse-instruction-fields (name format fields)
  514.   (declare (type cformat format))
  515.   (let ((format-fields (format-fields format)))
  516.     (collect ((fields-done)
  517.           (res))
  518.       (dolist (field fields)
  519.     (destructuring-bind (field-name &key constant argument same-as function
  520.                     (read nil read-p) (write nil write-p)
  521.                     type inverse-function mask)
  522.                 field
  523.       (declare (ignore type inverse-function mask))
  524.       (let ((field (find field-name format-fields :key #'field-name)))
  525.         (unless field
  526.           (error "In instruction ~S: format ~S doesn't have a field named ~S."
  527.              name (format-name format) field-name))
  528.         (when (member field-name (fields-done))
  529.           (error "Field ~S listed twice in instruction ~S." field-name name))
  530.         (fields-done field-name)
  531.         (unless (eql (count-if #'identity (list constant argument same-as)) 1)
  532.           (error "Must specify one of :constant, :argument, or :same-as ~
  533.                     for field ~S of format ~S in instruction ~S."
  534.              field-name (format-name format) name))
  535.         (res (make-field-parse
  536.           :name field-name
  537.           :kind (cond (constant :constant)
  538.                   (argument :argument)
  539.                   (t
  540.                    (assert same-as)
  541.                    :same-as))
  542.           :what (or constant argument same-as)
  543.           :special-type
  544.           (gethash argument
  545.                (backend-special-arg-types *target-backend*))
  546.           
  547.           :function function
  548.           :read-p (if read-p
  549.                   read
  550.                   (and (not constant)
  551.                    (field-read-p field)))
  552.           :write-p (if write-p
  553.                    write
  554.                    (and (not constant)
  555.                     (field-write-p field))))))))
  556.                    
  557.       (dolist (format-field format-fields)
  558.     (unless (member (field-name format-field) (fields-done))
  559.       (cond ((field-default-p format-field)
  560.          (res (make-field-parse :name (field-name format-field)
  561.                     :kind :constant
  562.                     :what (field-default format-field))))
  563.         ((field-default-type format-field)
  564.          (res (make-field-parse :name (field-name format-field)
  565.                     :kind :argument
  566.                     :what (field-default-type format-field)
  567.                     :special-type
  568.                      (gethash (field-default-type format-field)
  569.                           (backend-special-arg-types *target-backend*))
  570.                     :read-p (field-read-p format-field)
  571.                     :write-p (field-write-p format-field))))
  572.         (t
  573.          (error
  574.           "Field ~S of format ~S in instruction ~S cannot be defaulted."
  575.           (field-name format-field) (format-name format) name)))))
  576.  
  577.       (res))))
  578.  
  579.  
  580. ;;; SELECT-ACCESSORS  --  Internal
  581. ;;;
  582. ;;;    Annotate a list of FIELD-INFO structures with the appropriate
  583. ;;; instruction slot accessors and argument variables.  We ignore :CONSTANT
  584. ;;; fields, since we tacitly assume that they never are TNs (which eliminates
  585. ;;; the need to explicitly clear any default :READ or :WRITE attributes.)
  586. ;;;
  587. ;;;    We do three passes over the fields.  In the first pass, we assign the
  588. ;;; variables for arguments.  In the second pass, we copy the variables for
  589. ;;; same-as arguments.  In the final pass, we set up accessors for both.
  590. ;;;
  591. (defun select-accessors (fields)
  592.   (declare (list fields))
  593.   (let ((argument instruction-argument-slots)
  594.     (result instruction-result-slots)
  595.     (constant instruction-constant-slots)
  596.     (arg-num 0))
  597.     (dolist (field fields)
  598.       (when (eq (field-parse-kind field) :argument)
  599.     (setf (field-parse-argument field) (nth-argument arg-num))
  600.     (incf arg-num)))
  601.  
  602.     (dolist (field fields)
  603.       (when (eq (field-parse-kind field) :same-as)
  604.     (let ((as (find (field-parse-what field) fields
  605.             :key #'field-parse-name)))
  606.       (unless (and as
  607.                (eq (field-parse-kind as) :argument))
  608.         (error "Value for :SAME-AS in field ~S is not an argument field:~
  609.                 ~%  ~S"
  610.            (field-parse-name field) (field-parse-what field)))
  611.       (setf (field-parse-argument field) (field-parse-argument as)))))
  612.          
  613.  
  614.     (dolist (field fields)
  615.       (macrolet ((getacc (where)
  616.            `(push (or (pop ,where)
  617.                   (error "Too few ~S fields configured in the use ~
  618.                           of DEFINE-INSTRUCTION-STRUCTURE."
  619.                      ',where))
  620.               (field-parse-accessors field))))
  621.     (unless (eq (field-parse-kind field) :constant)
  622.       (let ((read-p (field-parse-read-p field))
  623.         (write-p (field-parse-write-p field)))
  624.         (cond ((or read-p write-p)
  625.            (when read-p (getacc argument))
  626.            (when write-p (getacc result)))
  627.           (t
  628.            (getacc constant))))))))
  629.   (undefined-value))
  630.  
  631.  
  632. ;;; FIND-ARG-TYPES  --  Internal
  633. ;;;
  634. ;;;    Given a list of fields, return a list of the Lisp type of each argument.
  635. ;;;
  636. (defun find-arg-types (fields)
  637.   (declare (list fields))
  638.   (collect ((res))
  639.     (dolist (field fields)
  640.       (when (eq (field-parse-kind field) :argument)
  641.     (res (or (car (field-parse-special-type field))
  642.          (field-parse-what field)))))
  643.     (res)))
  644.  
  645.  
  646. ;;; PARSE-META-INSTRUCTION  --  Internal
  647. ;;;
  648. ;;;    Return a META-INSTRUCTION structure describing the result of parsing the
  649. ;;; specified Options, taking defaults from the Default meta-instruction.
  650. ;;;
  651. (defun parse-meta-instruction (options default)
  652.   (declare (list options) (type meta-instruction default))
  653.   (destructuring-bind (&key (use nil use-p) (clobber nil clobber-p)
  654.                 (pinned nil pinned-p)
  655.                 (attributes nil attributes-p) (cost nil cost-p)
  656.                 disassem-printer disassem-control
  657.                 properties)
  658.       options
  659.     (declare (ignore disassem-printer disassem-control))
  660.     (let ((props (copy-list (meta-instruction-properties default))))
  661.       (do ((prop properties (cddr prop)))
  662.       ((endp prop))
  663.     (setf (getf props (first prop)) (second prop)))
  664.       (make-meta-instruction
  665.        :use (if use-p use (meta-instruction-use default))
  666.        :clobber (if clobber-p clobber (meta-instruction-clobber default))
  667.        :pinned (if pinned-p pinned (meta-instruction-pinned default))
  668.        :cost (if cost-p cost (meta-instruction-cost default))
  669.        :attributes (if attributes-p
  670.                attributes
  671.                (meta-instruction-attributes default))
  672.        :properties props))))
  673.  
  674.  
  675. ;;; PARSE-INSTRUCTION-FLAVOR  --  Internal
  676. ;;;
  677. ;;;    Return an INSTRUCTION-FLAVOR structure describing a particular flavor of
  678. ;;; the instruction Name.  Spec is the Flavor spec and Num is the flavor
  679. ;;; number.  Options is the options supplied for the whole instruction definition.
  680. ;;;
  681. (defun parse-instruction-flavor (name num options spec)
  682.   (declare (symbol name) (type index num) (list options))
  683.   (destructuring-bind (format &rest fields)
  684.               spec
  685.     (multiple-value-bind (format flav-options)
  686.              (if (consp format)
  687.                  (values (first format) (rest format))
  688.                  (values format nil))
  689.       (let* ((format (format-or-lose format))
  690.          (fields (parse-instruction-fields name format fields)))
  691.     (select-accessors fields)
  692.     (make-instruction-flavor
  693.      :name name
  694.      :format format
  695.      :number num
  696.      :fields fields
  697.      :arg-types (find-arg-types fields)
  698.      :nargs (count :argument fields :key #'field-parse-kind)
  699.      :meta-instruction
  700.      (parse-meta-instruction
  701.       flav-options
  702.       (parse-meta-instruction
  703.        options
  704.        (format-meta-instruction format))))))))
  705.  
  706.  
  707. ;;;; Instruction info creation:
  708.  
  709. ;;; MAKE-EMITTER-FUNCTION  --  Internal
  710. ;;;
  711. ;;;    Return an emitter function for the specified instruction Flavor.  This
  712. ;;; function just binds each field name to its actual value, and then calls the
  713. ;;; format emit function on those values.  Finding the value is only
  714. ;;; non-trivial when it is an argument, in which case we must access the value
  715. ;;; from the INSTRUCTION structure, calling an additional conversion function
  716. ;;; when the type is a special argument kind.
  717. ;;;
  718. (defun make-emitter-function (flavor)
  719.   (declare (type instruction-flavor flavor))
  720.   (let ((format (instruction-flavor-format flavor)))
  721.     (collect ((bindings)
  722.           (same-as-bindings))
  723.       (dolist (field (instruction-flavor-fields flavor))
  724.     (let ((name (field-parse-name field))
  725.           (fun (field-parse-function field))
  726.           (what (field-parse-what field)))
  727.       (ecase (field-parse-kind field)
  728.         (:constant
  729.          (bindings `(,name ,(maybe-funcall fun what))))
  730.         (:same-as
  731.          (same-as-bindings `(,name ,(maybe-funcall fun what))))
  732.         (:argument
  733.          (bindings
  734.           `(,name 
  735.         ,(maybe-funcall
  736.           fun
  737.           (maybe-funcall (cdr (field-parse-special-type field))
  738.                  `(,(first (field-parse-accessors field))
  739.                    inst)))))))))
  740.       
  741.       `#'(lambda (buffer where inst)
  742.        (declare (ignorable buffer where inst))
  743.        (let* (,@(bindings)
  744.           ,@(same-as-bindings))
  745.          (,(format-emitter format)
  746.           buffer
  747.           where
  748.           ,@(mapcar #'field-name (format-fields format))))))))
  749.  
  750.  
  751. ;;; CREATE-INSTRUCTION-INFO  --  Internal
  752. ;;;
  753. ;;;    Return a form to create the INSTRUCTION-INFO structure for a particular
  754. ;;; instruction Flavor.
  755. ;;;
  756. (defun create-instruction-info (flavor)
  757.   (declare (type instruction-flavor flavor))
  758.   (let ((meta-inst (instruction-flavor-meta-instruction flavor)))
  759.     `(make-instruction-info
  760.       :name ',(instruction-flavor-name flavor)
  761.       :flavor ,(instruction-flavor-number flavor)
  762.       :kind :normal
  763.       :length ,(format-length (instruction-flavor-format flavor))
  764.       :use ,(parse-resources (meta-instruction-use meta-inst))
  765.       :clobber ,(parse-resources (meta-instruction-clobber meta-inst))
  766.       :pinned ,(meta-instruction-pinned meta-inst)
  767.       :attributes (instruction-attributes ,@(meta-instruction-attributes meta-inst))
  768.       :cost ,(meta-instruction-cost meta-inst)
  769.       :properties (list ,@(collect ((res))
  770.                 (do ((prop (meta-instruction-properties meta-inst)
  771.                        (cddr prop)))
  772.                 ((endp prop)
  773.                  (res))
  774.                   (res `',(first prop))
  775.                   (res (second prop)))))
  776.       :emitter ,(make-emitter-function flavor))))
  777.  
  778.  
  779. ;;;; Selector function creation:
  780.  
  781. ;;; CREATE-INSTRUCTION-FORM  --  Internal
  782. ;;;
  783. ;;;    Return a form to create an instruction of the specified Flavor, getting
  784. ;;; the arguments from the argument variables.
  785. ;;;
  786. (defun create-instruction-form (flavor)
  787.   (declare (type instruction-flavor flavor))
  788.   (let ((args (make-list (length instruction-slot-order)
  789.              :initial-element nil)))
  790.     (dolist (field (instruction-flavor-fields flavor))
  791.       (dolist (slot (field-parse-accessors field))
  792.     (setf (elt args (position slot instruction-slot-order))
  793.           (field-parse-argument field))))
  794.     `(make-instruction after ,(instruction-flavor-info-var flavor) ,@args)))
  795.  
  796.  
  797. ;;; DISPATCHER-FOR-FLAVORS  --  Internal
  798. ;;;
  799. ;;;    Do stuff to select the appropriate flavor of instruction Name from
  800. ;;; Flavors, all of which have Nargs arguments.  We return a form that does any
  801. ;;; necessary dispatching and creates an instruction of the appropriate flavor.
  802. ;;;
  803. (defun dispatcher-for-flavors (name nargs flavors)
  804.   (iterate frob
  805.        ((index 0)
  806.         (flavors flavors))
  807.     (cond ((= index nargs)
  808.        (unless (= (length flavors) 1)
  809.          (error "Multiple flavors of ~S have the same type signature: ~S"
  810.             name flavors))
  811.        (create-instruction-form (first flavors)))
  812.       (t
  813.        (collect ((tests))
  814.          (dolist (flavor flavors)
  815.            (let* ((type (nth index (instruction-flavor-arg-types flavor)))
  816.               (found (or (assoc type (tests) :test #'equal)
  817.                  (let ((res (list type)))
  818.                    (tests res)
  819.                    res))))
  820.          (nconc found (list flavor))))
  821.            (if (rest (tests))
  822.            `(etypecase ,(nth-argument index)
  823.               ,@(mapcar #'(lambda (test)
  824.                     `(,(car test)
  825.                       ,(frob (1+ index) (cdr test))))
  826.                 (tests)))
  827.            (frob (1+ index) (cdr (first (tests))))))))))
  828.  
  829.  
  830. ;;; MAKE-SELECTOR-DECLARATION  --  Internal
  831. ;;;
  832. ;;;    Return a list of the types of all possible arguments to the specified
  833. ;;; flavors in each position, for use in a function type declaration.  This is
  834. ;;; our main mechanism for enforcing instruction argument types.
  835. ;;;
  836. (defun make-selector-declaration (nargs flavors)
  837.   (declare (list flavors))
  838.   (loop for i below nargs 
  839.     collect `(or ,@(loop for flavor in flavors
  840.              collect (elt (instruction-flavor-arg-types flavor) i)))))
  841.  
  842.  
  843. ;;; MAKE-SELECTOR-FUNCTIONS  --  Internal
  844. ;;;
  845. ;;;    Return a list of forms to define selector functions and instantiate them
  846. ;;; in the back end, given a list of instruction flavors.
  847. ;;;
  848. (defun make-selector-functions (flavors)
  849.   (let ((by-counts (make-hash-table))
  850.     (name (instruction-flavor-name (first flavors))))
  851.     (dolist (flav flavors)
  852.       (let ((nargs (instruction-flavor-nargs flav)))
  853.     (setf (gethash nargs by-counts)
  854.           (nconc (gethash nargs by-counts) (list flav)))))
  855.     (collect ((entries)
  856.           (forms))
  857.       (loop for similar-flavors being each hash-value in by-counts do
  858.     (let* ((nargs (instruction-flavor-nargs (first similar-flavors)))
  859.            (defun-name (intern (format nil "~:@(append-~R-arg-~A-inst~)"
  860.                        nargs name))))
  861.       (entries (cons nargs defun-name))
  862.       (forms
  863.        `(declaim (ftype (function ,(make-selector-declaration
  864.                     nargs similar-flavors)
  865.                       instruction)
  866.                 ,defun-name)))
  867.       (forms
  868.        `(defun ,defun-name
  869.            ,(loop for i below nargs
  870.               collect (nth-argument i))
  871.           (let* ((segment *current-segment*)
  872.              (after (segment-last segment))
  873.              (inst ,(dispatcher-for-flavors name nargs similar-flavors)))
  874.         (setf (node-next after) inst)
  875.         (setf (segment-last segment) inst)
  876.         inst)))))
  877.       (forms `(eval-when (compile load eval)
  878.         (setf (gethash ,(symbol-name name)
  879.                    (backend-instruction-flavors *target-backend*))
  880.               ',(entries))))
  881.       (forms))))
  882.  
  883. ); eval-when (compile load eval)
  884.  
  885.  
  886. ;;;; Definition macros.
  887.  
  888.  
  889. ;;; DEFINE-RESOURCES  --  Public
  890. ;;;
  891. (defmacro define-resources (&rest names)
  892.   "List the random resources that instructions can frob."
  893.   `(eval-when (compile load eval)
  894.      (setf (backend-assembler-resources *target-backend*) ',names)))
  895.  
  896.  
  897. ;;; DEFINE-ARGUMENT-TYPE  --  Public
  898. ;;;
  899. (defmacro define-argument-type (name &rest options
  900.                      &key (type t)
  901.                           function
  902.                       disassem-printer
  903.                       sign-extend
  904.                       disassem-use-label)
  905.   "Define a ``magic'' argument type.  When NAME is used as an argument type
  906.   use TYPE in the etypecase instead, and apply FUNCTION to the argument."
  907.   (declare (ignore disassem-printer sign-extend disassem-use-label))
  908.   `(progn
  909.      (eval-when (compile load eval)
  910.        (setf (gethash ',name
  911.               (backend-special-arg-types *target-backend*))
  912.          (cons ,type
  913.            ',function)))
  914.      ,(disassem:gen-field-type-decl-form name options)
  915.      ',name))
  916.  
  917.  
  918. (defmacro define-fixup-type (type &rest dat-args)
  919.   "Define argument TYPE as being a fixup.  TYPE is automatically registered
  920.   as a ``magic'' argument type with a function to record the fixup when
  921.   the instruction using this argument is emitted."
  922.   (let ((record-function (intern (concatenate 'simple-string
  923.                           "RECORD-"
  924.                           (symbol-name type)
  925.                           "-FIXUP")))
  926.     (arg-type (intern (concatenate 'simple-string
  927.                        (symbol-name type)
  928.                        "-FIXUP"))))
  929.     `(progn
  930.        (defun ,record-function (fixup)
  931.      (push (list ',type fixup *current-position*) *fixups*)
  932.      (or (fixup-offset fixup) 0))
  933.        (define-argument-type ,arg-type
  934.      :type 'fixup
  935.      :function ,record-function
  936.      ,@dat-args)
  937.        ',type)))
  938.  
  939.  
  940. ;;; The place where we pick up defaults for instruction format meta-instruction
  941. ;;; options.
  942. ;;;
  943. (eval-when (compile load eval)
  944.   (defparameter *format-default-options* (make-meta-instruction)))
  945.  
  946. (defmacro define-format ((format bits &rest options) &rest fields)
  947.   "DEFINE-FORMAT (Format Bits Keywords*)
  948.    {(Field-Name Byte-Spec Field-Keywords*)}*
  949.   Define a new instruction format named FORMAT and being BITS bits wide.
  950.   Possible keywords for fields are :DEFAULT, :FUNCTION, :READ, and :WRITE."
  951.   (unless (zerop (rem bits vm:*assembly-unit-length*))
  952.     (warn "Format ~S uses ~D bits, which is not a multiple of ~
  953.            vm:*assembly-unit-length* (~D)"
  954.       format bits vm:*assembly-unit-length*))
  955.   (let ((mask (ash -1 bits))
  956.     (args nil)
  957.     (bindings nil)
  958.     (bytes (make-array (truncate bits vm:*assembly-unit-length*)
  959.                :initial-element nil))
  960.     (format-fields nil)
  961.     (types nil)
  962.     (binding-types nil))
  963.     (dolist (field fields)
  964.       (destructuring-bind (name bytespec &key (default 0 default-p) default-type function
  965.                 read write)
  966.               field
  967.     (let* ((bytespec (eval bytespec))
  968.            (size (byte-size bytespec))
  969.            (posn (byte-position bytespec)))
  970.       (unless (zerop (ldb bytespec mask))
  971.         (warn "Field ~S overlaps in ~S"
  972.           name format))
  973.       (setf mask (dpb -1 bytespec mask))
  974.       (push name args)
  975.       (when function
  976.         (push `(,name (,function ,name)) bindings))
  977.       (multiple-value-bind
  978.           (start offset)
  979.           (floor posn vm:*assembly-unit-length*)
  980.         (let ((end (floor (1- (+ posn size))
  981.                   vm:*assembly-unit-length*)))
  982.           (cond ((zerop size))
  983.             ((= start end)
  984.              (push (maybe-ash `(ldb (byte ,size 0) ,name)
  985.                       offset)
  986.                (svref bytes start)))
  987.             (t
  988.              (push (maybe-ash
  989.                 `(ldb (byte ,(- vm:*assembly-unit-length*
  990.                         offset)
  991.                     0)
  992.                   ,name)
  993.                 offset)
  994.                (svref bytes start))
  995.              (do ((index (1+ start) (1+ index)))
  996.              ((>= index end))
  997.                (push
  998.             `(ldb (byte ,vm:*assembly-unit-length*
  999.                     ,(- (* vm:*assembly-unit-length*
  1000.                        (- index start))
  1001.                     offset))
  1002.                   ,name)
  1003.             (svref bytes index)))
  1004.              (let ((len (rem (+ size offset)
  1005.                      vm:*assembly-unit-length*)))
  1006.                (push
  1007.             `(ldb (byte ,(if (zerop len)
  1008.                      vm:*assembly-unit-length*
  1009.                      len)
  1010.                     ,(- (* vm:*assembly-unit-length*
  1011.                        (- end start))
  1012.                     offset))
  1013.                   ,name)
  1014.             (svref bytes end)))))))
  1015.       (cond ((zerop size)
  1016.          (push `(ignore ,name) types))
  1017.         (function
  1018.          (push `(type (signed-byte ,(1+ size)) ,name)
  1019.                binding-types))
  1020.         (t
  1021.          (push `(type (signed-byte ,(1+ size)) ,name) types)))
  1022.       (push `(make-field :name ',name
  1023.                  :default ',default
  1024.                  :default-p ',default-p
  1025.                  :default-type ',default-type
  1026.                  :read-p ',read
  1027.                  :write-p ',write)
  1028.         format-fields))))
  1029.     (ecase (backend-byte-order *target-backend*)
  1030.       (:big-endian
  1031.        (setf bytes (nreverse bytes)))
  1032.       (:little-endian))
  1033.     (unless (= mask -1)
  1034.       (warn "Empty space in ~S; assuming zero filled." format))
  1035.     (let ((emitter-fn (intern (concatenate 'simple-string
  1036.                        (symbol-name format)
  1037.                        "-FORMAT-EMITTER"))))
  1038.       `(progn
  1039.      (defun ,emitter-fn (buffer where ,@(nreverse args))
  1040.        (declare
  1041.         (type (simple-array (unsigned-byte ,vm:*assembly-unit-length*)
  1042.                 (*))
  1043.           buffer)
  1044.         (fixnum where)
  1045.         (ignorable buffer where)
  1046.         ,@(nreverse types))
  1047.        (let ,(nreverse bindings)
  1048.          (declare ,@(nreverse binding-types))
  1049.          ,@(let ((sets nil))
  1050.          (dotimes (i (length bytes))
  1051.            (push `(setf (aref buffer (+ where ,i))
  1052.                 (logior ,@(svref bytes i)))
  1053.              sets))
  1054.          (nreverse sets))))
  1055.      (eval-when (compile load eval)
  1056.        (setf (gethash ',format
  1057.               (backend-instruction-formats *target-backend*))
  1058.          (make-format
  1059.           :name ',format
  1060.           :meta-instruction
  1061.           ',(parse-meta-instruction options *format-default-options*)
  1062.           :length ,(ceiling bits vm:*assembly-unit-length*)
  1063.           :fields (list ,@(nreverse format-fields))
  1064.           :emitter ',emitter-fn)))
  1065.      ,(disassem:gen-inst-format-decl-form format bits fields options)
  1066.      ',format))))
  1067.  
  1068. (defmacro define-instruction ((name &rest options) &rest flavors)
  1069.   "DEFINE-INSTRUCTION (Name {Key Value}*)) Flavor-Spec*
  1070.   Define a new instruction named NAME.  Each instruction may have several
  1071.   flavors selected according to argument count and type.  A Flavor-Spec is:
  1072.       (Format {(Field {Field-Key Value}*)}*)
  1073.  
  1074.   Each flavor specifies what format and where to get the values to fill its
  1075.   fields.  Each field must specify exactly one of :CONSTANT, :ARGUMENT, or
  1076.   :SAME-AS, indicating the source of the value for that field.  If a field
  1077.   defined in the format is not specified, then its value is taken from the
  1078.   format default (if any.)  These are the Field-Keys:
  1079.  
  1080.   :CONSTANT Value
  1081.       Specifies that this field always has the specified constant value.
  1082.  
  1083.   :ARGUMENT Type
  1084.       Specifies that this the value of this field is obtained from an argument,
  1085.       and must be of the specified Type.  Type may be any Lisp type specifier,
  1086.       or an argument type defined by DEFINE-ARGUMENT-TYPE.
  1087.  
  1088.   :SAME-AS Field
  1089.       Specifies that this field has the same value as the other named field.
  1090.  
  1091.   :READ T-or-NIL
  1092.   :WRITE T-or-NIL
  1093.       If true in an argument field, indicates that the argument is a TN which
  1094.       is read (or written) by this instruction.
  1095.  
  1096.   :FUNCTION Fun-Form
  1097.       Fun-Form specifies a function that does instruction specific
  1098.       transformation of the numeric value of a field.  This in called after
  1099.       any DEFINE-ARGUMENT-TYPE :FUNCTION, but before any DEFINE-FORMAT :FUNCTION."
  1100.  
  1101.   (let ((parsed-flavors
  1102.      (loop for spec in flavors and num from 0
  1103.        collect (parse-instruction-flavor name num options spec))))
  1104.     `(let ,(mapcar #'(lambda (flav)
  1105.                `(,(instruction-flavor-info-var flav)
  1106.              ,(create-instruction-info flav)))
  1107.            parsed-flavors)
  1108.        ,@(make-selector-functions parsed-flavors)
  1109.        ,(disassem:gen-inst-decl-form name flavors options)
  1110.        ',name)))
  1111.  
  1112.  
  1113. (defmacro define-pseudo-instruction (name max-bits lambda-list &body body)
  1114.   "Define NAME as being a pseudo-instruction that can be up to MAX-BITS wide.
  1115.   LAMBDA-LIST and BODY specify the function to use to expand the
  1116.   pseudo-instruction into other instructions."
  1117.   (let ((append-name (intern (concatenate 'simple-string
  1118.                       "APPEND-"
  1119.                       (string name)
  1120.                       "-PSEUDO-INSTRUCTION")))
  1121.     (expander-name (intern (concatenate 'simple-string
  1122.                         (string name)
  1123.                         "-PSEUDO-INSTRUCTION-EXPANDER")))
  1124.     (n-info (gensym))
  1125.     (args (make-list (length instruction-slot-order) :initial-element nil)))
  1126.     (setf (elt args (position (first instruction-constant-slots)
  1127.                   instruction-slot-order))
  1128.       'args)
  1129.     `(progn
  1130.        (defun ,expander-name ,lambda-list
  1131.      ,@body)
  1132.        (let ((,n-info (make-instruction-info
  1133.                :name ',name
  1134.                :flavor 0
  1135.                :kind :pseudo
  1136.                :length ',(ceiling max-bits vm:*assembly-unit-length*)
  1137.                :emitter #',expander-name)))
  1138.      (defun ,append-name (&rest args)
  1139.        (let* ((segment *current-segment*)
  1140.           (after (segment-last segment))
  1141.           (inst (make-instruction after ,n-info ,@args)))
  1142.          (setf (node-next after) inst)
  1143.          (setf (segment-last segment) inst)
  1144.          inst)))
  1145.        
  1146.        (eval-when (compile load eval)
  1147.      (setf (gethash ,(symbol-name name)
  1148.             (backend-instruction-flavors *target-backend*))
  1149.            ',append-name)))))
  1150.  
  1151.  
  1152. ;;;; Noise to emit instructions.
  1153.  
  1154. (defvar *current-segment*)
  1155. (defvar *current-vop*)
  1156.  
  1157. (defmacro inst (name &rest args)
  1158.   `(,(parser-or-lose name (length args)) ,@args))
  1159.  
  1160. (defun align (bits)
  1161.   (let* ((last (segment-last *current-segment*))
  1162.      (align (make-alignment :prev last :bits bits)))
  1163.     (setf (node-next last) align)
  1164.     (setf (segment-last *current-segment*) align)
  1165.     align))
  1166.  
  1167. (defun emit-label (label)
  1168.   (when (label-prev label)
  1169.     (error "Label ~S has already been emitted somewhere else." label))
  1170.   (setf (label-vop label) *current-vop*)
  1171.   (let ((last (segment-last *current-segment*)))
  1172.     (setf (label-prev label) last)
  1173.     (setf (node-next last) label))
  1174.   (setf (segment-last *current-segment*) label))
  1175.  
  1176. (defun make-segment ()
  1177.   (let ((segment (%make-segment)))
  1178.     (setf (segment-last segment) segment)
  1179.     segment))
  1180.  
  1181. (defun insert-segment (segment)
  1182.   (when (segment-prev segment)
  1183.     (error "Segment ~S has already been inserted somewhere else." segment))
  1184.   (let ((last (segment-last *current-segment*)))
  1185.     (setf (node-next last) segment)
  1186.     (setf (segment-prev segment) last)
  1187.     (setf (segment-last *current-segment*) (segment-last segment))))
  1188.  
  1189.  
  1190. (defmacro assemble ((segment &optional (vop nil vop-p))
  1191.             &body forms)
  1192.   `(let ((*current-segment* ,segment)
  1193.      ,@(when vop-p
  1194.          `((*current-vop* ,vop))))
  1195.      (when (segment-prev *current-segment*)
  1196.        (error "Segment ~S has already been inserted -- can't extend it now."
  1197.           *current-segment*))
  1198.      ,@forms))
  1199.  
  1200.  
  1201.  
  1202. ;;;; emit-code-vector
  1203.  
  1204. (defconstant output-buffer-size (* 8 1024))
  1205.  
  1206. (defvar *output-buffer*
  1207.   (make-array output-buffer-size
  1208.           :element-type '(unsigned-byte #.vm:*assembly-unit-length*)
  1209.           :initial-element 0))
  1210.  
  1211. (defvar *current-position*)
  1212. (declaim (type index *current-position*))
  1213.  
  1214. (defvar *fixups*)
  1215.  
  1216. (declaim (inline node-size))
  1217. (defun node-size (current worst-case-p set-label-locs)
  1218.   (etypecase current
  1219.     (instruction
  1220.      (instruction-length current))
  1221.     (label
  1222.      (when set-label-locs
  1223.        (setf (label-%position current) *current-position*))
  1224.      0)
  1225.     (alignment
  1226.      (if worst-case-p
  1227.      (ash 1 (alignment-bits current))
  1228.      (logand (- *current-position*) (1- (ash 1 (alignment-bits current))))))))
  1229.  
  1230.  
  1231. (defmacro do-nodes ((node-var segment worst-case set-label-locs)
  1232.             &body forms)
  1233.   `(let ((*current-position* 0))
  1234.      (do ((,node-var ,segment (node-next ,node-var)))
  1235.      ((null ,node-var))
  1236.        ,@forms
  1237.        (incf *current-position*
  1238.          (node-size ,node-var ,worst-case ,set-label-locs)))
  1239.      *current-position*))
  1240.  
  1241. (defun expand-pseudo-instructions (segment)
  1242.   ;; Make a first guess at the position of things.
  1243.   (do-nodes (node segment t t))
  1244.   ;; Expand any pseduo-instructions.
  1245.   (do-nodes (node segment nil t)
  1246.     (when (instruction-p node)
  1247.       (let ((info (instruction-info node)))
  1248.     (when (eq (instruction-info-kind info) :pseudo)
  1249.       (let ((new-seg (make-segment)))
  1250.         (assemble (new-seg (node-vop node))
  1251.           (apply (instruction-info-emitter info)
  1252.              (instruction-constant-zero node)))
  1253.         (cond ((eq new-seg (segment-last new-seg))
  1254.            ;; Nothing was inserted, just delete this puppy.
  1255.            (when (node-next node)
  1256.              (setf (node-prev (node-next node))
  1257.                (node-prev node)))
  1258.            (setf (node-next (node-prev node))
  1259.              (node-next node)))
  1260.           (t
  1261.            ;; Link the segment contents in place of node.
  1262.            (setf (node-next (node-prev node))
  1263.              (segment-next new-seg))
  1264.            (setf (node-prev (segment-next new-seg))
  1265.              (node-prev node))
  1266.            (setf (node-next (segment-last new-seg))
  1267.              (node-next node))
  1268.            (when (node-next node)
  1269.              (setf (node-prev (node-next node))
  1270.                (segment-last new-seg)))))
  1271.         (setf node new-seg))))))
  1272.   (undefined-value))
  1273.  
  1274. (defun finalize-segment (segment)
  1275.   ;; Determine the actual positions.
  1276.   (do-nodes (node segment nil t)))
  1277.  
  1278.  
  1279. (defun emit-code-vector (stream segment)
  1280.   ;; Emit the instructions.
  1281.   (let ((offset 0)
  1282.     (*fixups* nil))
  1283.     (do-nodes (node segment nil nil)
  1284.       (let ((size (node-size node nil nil)))
  1285.     (when (> (+ offset size) output-buffer-size)
  1286.       (write-string *output-buffer* stream :end offset)
  1287.       (setf offset 0))
  1288.     (etypecase node
  1289.       (instruction
  1290.        (funcall (instruction-info-emitter (instruction-info node))
  1291.             *output-buffer*
  1292.             offset
  1293.             node))
  1294.       (label)
  1295.       (alignment
  1296.        (fill *output-buffer* 0 :start offset :end (+ offset size))))
  1297.     (incf offset size)))
  1298.     (unless (zerop offset)
  1299.       (write-string *output-buffer* stream :end offset))
  1300.     *fixups*))
  1301.  
  1302.  
  1303. (defun label-position (label)
  1304.   (or (label-%position label)
  1305.       (error "Label ~S was never emitted." label)))
  1306.  
  1307.  
  1308. ;;; DUMP-NODE  --  Internal
  1309. ;;;
  1310. (defun dump-node (node)
  1311.   (etypecase node
  1312.     (label
  1313.      (format t "~A:~%" node))
  1314.     (instruction
  1315.      (format t "~8X:~0,8T~A~@[~0,8T~{~A~^, ~}~]~%"
  1316.          *current-position*
  1317.          (instruction-info-name (instruction-info node))
  1318.          (collect ((args))
  1319.            (do-results (arg node)
  1320.          (args (c::location-print-name arg)))
  1321.            (do-arguments (arg node)
  1322.          (args (c::location-print-name arg)))
  1323.            (do-constants (arg node)
  1324.          (args arg))
  1325.            (args))))
  1326.     (alignment
  1327.      (format t "~8X:~0,8T.align~16T~D~%"
  1328.          *current-position*
  1329.          (alignment-bits node)))))
  1330.  
  1331. ;;; DUMP-SEGMENT  --  Interface
  1332. ;;;
  1333. ;;;    Print out the assembly code in a segment.  If supplied, Start and End
  1334. ;;; delimit a subsequence to print.  Markers is an alist (node . format-args)
  1335. ;;; of stuff to print out before the specified nodes.
  1336. ;;;
  1337. (defun dump-segment (segment &key
  1338.                  ((:stream *standard-output*) *standard-output*)
  1339.                  start end markers)
  1340.   (let ((last-vop nil)
  1341.     (started (not start)))
  1342.     (do-nodes (node segment nil nil)
  1343.       (when (eq node start) (setq started t))
  1344.       (when (eq node end) (return))
  1345.       (when started
  1346.     (let ((vop (node-vop node)))
  1347.       (when (and vop (not (eq last-vop vop)))
  1348.         (terpri)
  1349.         (princ "VOP ")
  1350.         (if (c::vop-p vop)
  1351.         (c::print-vop vop)
  1352.         (format t "~S~%" vop)))
  1353.       (setf last-vop vop))
  1354.     (dolist (marker markers)
  1355.       (when (and (eq (car marker) node) (cdr marker))
  1356.         (apply #'format t (cdr marker))))
  1357.     (dump-node node))))
  1358.   (values))
  1359.  
  1360. (defun count-instructions (fun segment elsewhere &optional (what :cost))
  1361.   (let ((elsewherep nil)
  1362.     (last-vop nil)
  1363.     (count 0))
  1364.     (flet ((note-vop-counts ()
  1365.          (when last-vop
  1366.            (funcall fun last-vop count elsewherep))
  1367.          (setf last-vop nil)))
  1368.       (do-nodes (node segment nil nil)
  1369.     (let ((vop (node-vop node))
  1370.           (value (ecase what
  1371.                (:cost
  1372.             (and (instruction-p node)
  1373.                  (instruction-info-cost (instruction-info node))))
  1374.                (:size
  1375.             (node-size node nil nil)))))
  1376.       (when value
  1377.         (cond ((eq vop last-vop)
  1378.            (incf count value))
  1379.           (t
  1380.            (note-vop-counts)
  1381.            (setf last-vop vop)
  1382.            (setf count value)))))
  1383.     (when (eq node elsewhere)
  1384.       (note-vop-counts)
  1385.       (setf elsewherep t)))
  1386.       (note-vop-counts))))
  1387.  
  1388. (defun nuke-segment (segment)
  1389.   (do ((node segment next)
  1390.        (next (node-next segment) (when next (node-next next))))
  1391.       ((null node))
  1392.     (typecase node
  1393.       (instruction
  1394.        (unmake-instruction node))
  1395.       (t
  1396.        (setf (node-vop node) nil)
  1397.        (setf (node-prev node) nil)
  1398.        (setf (node-next node) nil)))))
  1399.